package main

import (
	"fmt"
	"reflect"
)

type student struct {
	Name string `json:"name"`
	Score int `json:"score"`
}

func main() {
	stu1 := student{
		Name: "zyl1",
		Score: 100,
	}

	t := reflect.TypeOf(stu1)
	fmt.Println(t.Name(), t.Kind())

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fmt.Printf("name:%s index:%d type:%v json tag: %v\n", field.Name, field.Index, field.Type, field.Tag.Get("json"))
	}
	// 通过字段名获取指定结构体字段信息
	if scoreField, ok := t.FieldByName("score"); ok {
		fmt.Printf("name: %s index: %d type: %v json tag: %v\n", scoreField.Name, scoreField.Index, scoreField.Type, scoreField.Tag.Get("json"))
	}

	fmt.Println("--------------------------")
	PrintMethod(stu1)

}

func (s student) Study() string {
	msg := "好好学习， 天天向上"
	fmt.Println(msg)
	return msg
}
func (s student) Sleep() string {
	msg := "好好睡觉， 长得高"
	fmt.Println(msg)
	return msg
}
func PrintMethod(x interface{}) {
	t := reflect.TypeOf(x)
	v := reflect.ValueOf(x)

	fmt.Println(t.NumMethod())
	for i := 0; i < v.NumMethod(); i++ {
		methodType := v.Method(i).Type()
		// 打印方法名称
		fmt.Printf("method name: %s\n", t.Method(i).Name)
		// 方法类型
		fmt.Printf("method: %s\n", methodType)
		// 通过反射调用方法传参 必须是 []reflect.Value类型
		var args = []reflect.Value{}
		v.Method(i).Call(args)
	}
}
